package com.yw.thesimpllestplayer.extractor;

import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * @ProjectName: TheSimpllestplayer
 * @Package: com.yw.thesimpllestplayer.extractor
 * @ClassName: AVExtractor
 * @Description: 媒体提取器的父类
 * @Author: wei.yang
 * @CreateDate: 2021/11/2 14:23
 * @UpdateUser: 更新者：wei.yang
 * @UpdateDate: 2021/11/2 14:23
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 */
public abstract class BaseExtractor implements IExtractor {
    private static final String TAG = "BaseExtractor";


    /**
     * 媒体提取器
     */
    private MediaExtractor mediaExtractor;
    /**
     * 音频轨道
     */
    private int mAudioTrackIndex = -1;
    /**
     * 视频轨道
     */
    private int mVideoTrackIndex = -1;
    /**
     * 当前帧时间戳
     */
    private long mCurSampleTime = 0;
    /**
     * 当前帧标志位
     */
    private int mCurSampleFlag = 0;
    /**
     * 开始解码时间点
     */
    private long mStartDecodeSampleTime = 0;


    public BaseExtractor(@NonNull String mediaPath) {
        //设置数据源
        try {
            mediaExtractor = new MediaExtractor();
            mediaExtractor.setDataSource(mediaPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取视频轨
     *
     * @return
     */
    public MediaFormat getVideoFormat() {
        //获取轨道总数量
        int trackCount = mediaExtractor.getTrackCount();
        MediaFormat mediaFormat = null;
        for (int i = 0; i < trackCount; i++) {
            //获取MediaFormat
            mediaFormat = mediaExtractor.getTrackFormat(i);
            String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
            //如果
            if (mime.startsWith("video/")) {
                mVideoTrackIndex = i;
                break;
            }
        }
        if (mVideoTrackIndex >= 0) {
            return mediaFormat;
        }
        Log.e(TAG, "MediaFormat为空：mVideoTrackIndex-->" + mVideoTrackIndex);
        return null;
    }

    /**
     * 获取音频轨
     *
     * @return
     */
    public MediaFormat getAudioFormat() {
        int tackCount = mediaExtractor.getTrackCount();
        MediaFormat mediaFormat = null;
        for (int i = 0; i < tackCount; i++) {
            mediaFormat = mediaExtractor.getTrackFormat(i);
            String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
            if (mime.startsWith("audio/")) {
                mAudioTrackIndex = i;
                break;
            }
        }
        if (mAudioTrackIndex >= 0) {
            return mediaFormat;
        }
        return null;
    }

    /**
     * 读取媒体数据
     *
     * @param byteBuffer
     * @return
     */
    public int readBuffer(ByteBuffer byteBuffer) {
        byteBuffer.clear();
        selectTrack();
        int readSampleCount = 0;
        try {
            readSampleCount = mediaExtractor.readSampleData(byteBuffer, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (readSampleCount < 0) {
            return -1;
        }
        //记录当前帧时间戳
        mCurSampleTime = mediaExtractor.getSampleTime();
        //记录当前帧标志位
        mCurSampleFlag = mediaExtractor.getSampleFlags();
        //进入下一帧
        mediaExtractor.advance();
        return readSampleCount;

    }

    /**
     * 选择媒体轨道
     */
    private void selectTrack() {
        if (mVideoTrackIndex >= 0) {
            mediaExtractor.selectTrack(mVideoTrackIndex);
        } else if (mAudioTrackIndex >= 0) {
            mediaExtractor.selectTrack(mAudioTrackIndex);
        }
    }

    /**
     * seek到指定的位置，并返回实际时间戳
     *
     * @param pos seek到的位置
     * @return
     */
    public long seek(long pos) {
        mediaExtractor.seekTo(pos, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
        return mediaExtractor.getSampleTime();
    }

    /**
     * 停止读取数据
     */
    public void stop() {
        if (mediaExtractor != null) {
            mediaExtractor.release();
            mediaExtractor = null;
        }

    }

    /**
     * 获取视频轨索引
     *
     * @return
     */
    public int getVideoTrackIndex() {
        return mVideoTrackIndex;
    }

    /**
     * 获取音频轨索引
     *
     * @return
     */
    public int getAudioTrackIndex() {
        return mAudioTrackIndex;
    }

    /**
     * 设置开始解码时间戳
     *
     * @param pos
     */
    public void setStartDecodeSampleTime(long pos) {
        mStartDecodeSampleTime = pos;
    }

    /**
     * 获取当前帧时间
     *
     * @return
     */
    public long getCurrentTimestamp() {
        return mCurSampleTime;
    }

    /**
     * 获取当前帧标志位
     *
     * @return
     */
    public long getCurrentSampleFlag() {
        return mCurSampleFlag;
    }
}


